#pragma once
#include<iostream>
using namespace std;
#define INIT 10
template<class T>
class CirQueue
{
public:
	CirQueue()
	{
		_cq = new T[INIT];
		_front = _rear = 0;
	}
	void reseve(size_t n)
	{
		T* tmp = new T[n];
		size_t oldsize = size();
		for (size_t i = 0; i < oldsize; i++)
		{
			tmp[i] = _cq[i];
		}
		delete[] _cq;
		_cq = tmp;
		_front = 0;
		_rear = oldsize;
		_capacity *= 2;

	}
	bool full()
	{
		return (_rear + 1) % _capacity == _front;
	}
	bool empty()
	{
		return _rear == _front;
	}
	void push(const T& data)
	{
		if (full())
		{
			reseve(_capacity * 2);
		}
		_cq[_rear++] = data;
	}
	void pop()
	{
		_front++;
	}
	size_t size()
	{
		return (_rear - _front + _capacity) % _capacity;
	}
	T& top()
	{
		return _cq[_front];
	}
private:
	T* _cq;
	size_t _front;
	size_t _rear;
	int _capacity = INIT;
};

